#ifndef DUALDETECT_H
#define DUALDETECT_H

#include <QObject>
#include <opencv2/opencv.hpp>
#include "inc/rknn_api.h"
#include "aiimageutils.h"
#include "aipostprocess.h"

class DualDetect {

public:
     DualDetect(std::string labelNameTxTPath_, int objClassNum_);
    ~DualDetect();

    const int bg_color = 114;
    const int objClassNum = 11;
    const int objNumbMaxSize = 64;
    std::string labelNameTxTPath = "master/test/coco_80_labels_list.txt";

    bool loadModel(const QString &modelPath);
    int detect(const cv::Mat &baseImage,const cv::Mat &detecImage,object_detect_result_list *od_results);

    int getmodelDataSize() const{return modelDataSize;};
    const char* getSDKversion() const{return version.api_version;};
    int getimgWidth ()const{return rknn_app_ctx.model_width;};
    int getimgHeight ()const{return rknn_app_ctx.model_height;};
    int getimgChannel ()const{return rknn_app_ctx.model_channel;};

    float getobjThresh() const {return objThresh;};
    void setobjThresh(float objThresh_);
    float getnmsThresh() const {return nmsThresh;};
    void setnmsThresh(float nmsThresh_);

    char* getCocoClsToName(int &cls_id);
    cv::Mat cropToMultipleOf16(const cv::Mat& image);
    bool modelLoaded;
private:
    int modelDataSize;
    rknn_sdk_version version;
private:
    mutable std::mutex mutexRKNN_;
    struct Box {
        float x, y, w, h;
    };
    rknn_app_context_t rknn_app_ctx;
    rknn_tensor_mem *input_mems[1];
    rknn_tensor_mem *output_mems[12];
    int input_num ;

    letterbox_t letter_box;

    AiPostProcess *aiPostProcess;

    float objThresh;
    float nmsThresh;

    int modelInputWidth;
    int modelInputHeight;
    float boxConfThreshold;
    float nmsThreshold;
    unsigned char *modelData;


    bool preprocess(const cv::Mat &baseImage,const cv::Mat &detecImage,
                                image_buffer_t &dst_detect, image_buffer_t &dst_base);
    bool postprocess(const std::vector<float> &output, std::vector<cv::Rect> &boxes);
    void dump_tensor_attr(const rknn_tensor_attr *attr) const;

    cv::Mat letterbox_image(const cv::Mat &image, int target_width, int target_height,
                            const cv::Scalar &bg_color, letterbox_t &letter_box);
    letterbox_t preprocessImage(const cv::Mat &inputImage, cv::Mat &outputImage, int weight);
};

#endif // DUALDETECT_H
